package zju.dgm.util;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.NodeCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class CacheManager {


    @Resource
    private CuratorFramework client;

    private final ConcurrentHashMap<String, NodeCache> nodeCacheMap = new ConcurrentHashMap<>();

    private final ConcurrentHashMap<String, PathChildrenCache> pathChildrenCacheMap = new ConcurrentHashMap<>();

    /**
     * 从cache管理器中取NodeCache,如果没有会创建并start这个Cache
     *
     * @param path 指定监听的路径
     * @return 路径对应的NodeCache
     */
    public NodeCache getNodeCache(String path) {
        if (!nodeCacheMap.containsKey(path)) {
            try {
                NodeCache cache = new NodeCache(client, path);
                cache.start(true);// 这条比较关键，false会读一下初始值
                nodeCacheMap.put(path, cache);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return nodeCacheMap.get(path);
    }

    /**
     * 在指定node没被监听的情况下可以用
     * @param path 路径
     * @param buildInitial 是否读取初始值
     * @return
     */
    public NodeCache getNodeCache(String path, boolean buildInitial) {
        if (!nodeCacheMap.containsKey(path)) {
            try {
                NodeCache cache = new NodeCache(client, path);
                cache.start(buildInitial);// 这条比较关键，false会读一下初始值
                nodeCacheMap.put(path, cache);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return nodeCacheMap.get(path);
    }

    /**
     * 从cache管理器中取PathChildrenCache,如果没有会创建并start这个Cache
     * @param path 指定监听的路径
     * @return 路径对应的PathChildrenCache
     */
    public PathChildrenCache getPathChildrenCache(String path) {
        if (!pathChildrenCacheMap.containsKey(path)) {
            try {
                PathChildrenCache cache = new PathChildrenCache(client, path, false);
                cache.start();
                pathChildrenCacheMap.put(path, cache);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return pathChildrenCacheMap.get(path);
    }
}
